import BaseEchart from '@/components/base/BaseEchart';
import { Spin } from 'antd';
import EChartsReact from 'echarts-for-react';
import moment from 'moment';
import { FC, useEffect, useMemo, useRef, useState } from 'react';
import styled from 'styled-components';
import { getHisData, GetHisResponse, pollingInterval } from '../api';
import { colors } from '../util';

const DataWrap = styled.div`
  height: 100%;
  .ant-spin-nested-loading,
  .ant-spin-container {
    height: 100%;
    display: flex;
    overflow: hidden;
    flex-direction: column;
  }
`;
export interface HisDataProps {
  data?: { CName: string; EName: string; unit: string }[];
  type: '0' | '1' | '2';
  times?: [string, string];
  radarId?: string | null;
  request?: (...args: any) => any;
}

const HisData: FC<HisDataProps> = (props) => {
  const { type, radarId, data = [], times, request = getHisData } = props;
  const [fields, title, yList, units] = useMemo(() => {
    const unitMap: Record<string, { unitIndex: number; unit: string }> = {};
    const yList: string[] = [];
    const eNames: string[] = [];
    const cNames: string[] = [];
    data.forEach((i) => {
      const index = yList.findIndex((u) => u === i.unit);
      eNames.push(i.EName);
      cNames.push(i.CName);
      if (index !== -1) {
        unitMap[i.EName] = {
          unitIndex: index,
          unit: i.unit
        };
      } else {
        yList.push(i.unit);
        unitMap[i.EName] = {
          unitIndex: yList.length - 1,
          unit: i.unit
        };
      }
    });
    return [eNames, cNames, yList, Object.values(unitMap)];
  }, [data]);
  const fieldStr = fields.join(',');
  const [loading, setLoading] = useState(false);
  const [chartData, setChartData] = useState<GetHisResponse>({
    dateList: []
  } as unknown as GetHisResponse);
  const previousTimeRef = useRef<string>();
  const echartRef = useRef<EChartsReact | null>();
  useEffect(() => {
    if (fields.length === 0 || !radarId) {
      return () => {
        /**/
      };
    }
    let timer: number | undefined;
    const timerFn = () => {
      timer = setTimeout(() => {
        setLoading(true);
        const [startTime, endTime] = times || [];
        request({
          type,
          field: fieldStr,
          radarId,
          startTime,
          endTime,
          previousTime: previousTimeRef.current
        }).then((res: any) => {
          if (res.ok) {
            const { dateList, ...resRest } = res.data;
            const [time] = dateList;
            if (time) {
              setChartData(({ dateList, ...rest }) => {
                const maps = {
                  dateList: [...dateList, ...res.data.dateList]
                } as GetHisResponse;
                fields.forEach((i) => {
                  maps[i] = {
                    valueList: [...rest[i].valueList, ...resRest[i].valueList],
                    unit: rest[i].unit
                  };
                });
                return maps;
              });
              previousTimeRef.current = time;
              if (echartRef.current) {
                const instance = echartRef.current.getEchartsInstance();
                instance.clear();
                // instance.setOption();
              }
            }
          }
          setLoading(false);
        });
        timerFn();
      }, pollingInterval);
    };
    setLoading(true);
    const [startTime, endTime] = times || [];
    request({
      type,
      field: fieldStr,
      radarId,
      startTime,
      endTime
    }).then((res: any) => {
      if (res.ok) {
        setChartData(res.data);
        const { dateList } = res.data;
        const time = dateList[dateList.length - 1];
        previousTimeRef.current = time;
        timerFn();
        setLoading(false);
      }
    });
    return () => {
      clearTimeout(timer);
    };
  }, [type, fieldStr, radarId, request, times]);
  const echart = useMemo(
    () => (
      <BaseEchart
        ref={(e) => {
          echartRef.current = e;
        }}
        style={{ height: '100%' }}
        key={fieldStr}
        option={{
          grid: {
            left: 40,
            right: 70,
            top: 40,
            bottom: 30
          },
          tooltip: {
            show: true,
            trigger: 'axis',
            formatter: (params: any) => {
              console.log(units);
              return `<b>${params[0].name}</b><br/>
              ${params.map(
                (i: any, index: number) =>
                  `<div>${i.seriesName} ${i.value} ${units[index].unit}</div>`
              )}
              `;
            }
          },
          legend: {
            data: title || [],
            show: true,
            textStyle: {
              color: '#fff'
            }
          },
          dataZoom: [
            {
              show: true,
              realtime: true,
              start: 0,
              end: 100,
              right: 20,
              orient: 'vertical',
              xAxisIndex: [0, 1]
            },
            {
              type: 'inside',
              realtime: true,
              start: 30,
              end: 70,
              orient: 'vertical',
              xAxisIndex: [0, 1]
            }
          ],
          xAxis: {
            type: 'category',
            axisLabel: {
              color: '#fff',
              formatter: (value: string) => moment(value).format('MM-DD HH:mm')
            },
            data: chartData.dateList
          },
          axisPointer: {
            link: [
              {
                xAxisIndex: 'all'
              }
            ]
          },
          yAxis:
            yList.length > 1
              ? yList.map((i) => ({
                  type: 'value',
                  name: i,
                  nameTextStyle: { color: '#fff' },
                  axisLabel: { color: '#fff' }
                }))
              : {
                  type: 'value',
                  name: yList[0],
                  nameTextStyle: { color: '#fff' },
                  axisLabel: { color: '#fff' }
                },
          series: fields.map((i, index) => ({
            name: title[index],
            data: chartData[i]?.valueList ?? [],
            symbol: 'circle',
            symbolSize: 15,
            yAxisIndex: units[index].unitIndex,

            lineStyle: {
              color: colors[index].color
            },
            itemStyle: {
              color: colors[index].color,
              borderColor: colors[index].borderColor,
              borderWidth: 3
            },
            type: 'line'
          }))
        }}
      />
    ),
    [chartData, fieldStr, fields, title, units, yList]
  );
  return (
    <DataWrap>
      <Spin spinning={loading}>
        {/* <div style={{ textAlign: 'center' }}>{title?.join(',')}</div> */}
        <div style={{ flex: 1, overflow: 'hidden' }}>{echart}</div>
      </Spin>
    </DataWrap>
  );
};

export default HisData;
